﻿#include <iostream>
using namespace std;

#include <set>
#include <map>
#include <string>

//template<class T> 
//void Print(T data) 
//{   //typeid(T).name() 以字符串的形式输出T的数据类型
//    cout << typeid(data).name() << " : " << data << endl;
//}
//
//int main()
//{
//    Print(2);
//    Print(3.14);
//    Print('c');
//    Print("string");
//    return 0;
//}


//template<class T>
//T Add(T left, T right)
//{
//    return a + b;
//}
//
//int main()
//{
//    cout << Add(1, 2) << endl;
//    cout << Add(1.0, 2) << endl;
//    return 0;
//}


//template<class T>
//T Add(T left, T right)
//{
//    cout << typeid(T).name() << endl;
//    return left + right;
//}
//
//double Add(double left, int right)
//{
//    cout << "_3Adddi" << endl;
//    return left + right;
//}
//
//int main()
//{
//    cout << Add(1.0, 2) << endl; 
//    cout << Add<int>(1.1, 2.2) << endl; 
//    cout << Add(1, 2.2) << endl; 
//    return 0;
//}

//template<class T1,class T2>
//T2 Add(T1 left, T2 right)
//{
//    return left + right;
//}
//
//int main()
//{
//    cout << Add(1.0, 2) << endl; 
//    cout << Add(1.0, 2.2) << endl; 
//    return 0;
//}

//int main()
//{
//    cout << Add((int)1.0, 2) << endl;    //对1.0进行强制类型转换
//    cout << Add(1.0, (double)2) << endl; //对2进行强制类型转换
//    return 0;
//}


//template<class T>
//T Add(T left, T right)
//{
//    cout << typeid(T).name() << endl;
//    return left + right;
//}
//
//double Add(double left, double right)
//{
//    cout << "_3Adddd" << endl;
//    return left + right;
//}
//
//int main()
//{
//    cout << Add(1.2, 2.3) << endl;
//    cout << Add(1, 2) << endl;
//    return 0;
//}

//template<class T> 
//class Test 
//{
//public:
//    Test() {}
//    Test(T n)
//        :_num(n)
//    {}
//
//    void print()
//    {
//        cout << typeid(T).name() << endl;
//        cout << _num << endl;
//    }
//
//private:
//    T _num;
//};
//
//int main()
//{
//    Test<int> i(1);
//    Test<char> c('a');
//    Test<double> d(3.14);
//    i.print();
//    c.print();
//    d.print();
//    return 0;
//}


//// 定义一个模板类型的静态数组
//template<class T, size_t N = 10>
//class _array
//{
//public:
//	_array()
//		:_size(N)
//	{}
//
//	T& operator[](size_t index) { return _arr[index]; }
//	const T& operator[](size_t index)const { return _arr[index]; }
//
//	size_t size()const { return _size; }
//	bool empty()const { return 0 == _size; }
//
//private:
//	T _arr[N];
//	size_t _size;
//};
//
//int main()
//{
//	_array<int, 5> i;
//	_array<char, 20> c;
//	return 0;
//}

//class Date //日期类
//{
//public:
//	Date() = default;
//	Date(int y, int m, int d)
//		:_y(y)
//		, _m(m)
//		, _d(d)
//	{}
//
//	bool operator<(const Date& d)
//	{
//		return _y < d._y
//			|| _y == d._y && _m < d._m
//			|| _y == d._y && _m == d._m && _d < d._d;
//	}
//
//	bool operator>(const Date& d)
//	{
//		return !(*this < d);
//	}
//
//	int _y;
//	int _m;
//	int _d;
//};
//
//// 函数模板 -- 参数匹配
//template<class T>
//bool Less(T left, T right)
//{
//	return left < right;
//}
//
//
////对Less函数模板进行特化
//template<>
//bool Less<Date*>(Date* left, Date* right)
//{
//	return *left < *right; //解引用转而调用Date自己的运算符重载
//}
//
//int main()
//{
//	Date d1(2022, 7, 7);
//	Date d2(2022, 7, 8);
//	Date* p1 = &d1;
//	Date* p2 = &d2;
//	cout << Less(p1, p2) << endl; 
//	return 0;
//}


//template<class T1, class T2>
//class Test
//{
//public:
//	Test() { cout << "Data<T1, T2>" << endl; }
//private:
//	T1 _d1;
//	T2 _d2;
//};
//
//template<>
//class Test<int, char>
//{
//public:
//	Test() { cout << "Data<int, char>" << endl; }
//private:
//	int _d1;
//	char _d2;
//};
//
//int main()
//{
//	Test<int, int> d1;
//	Test<int, char> d2;
//	return 0;
//}

//两个参数偏特化为指针类型
//template <typename T1, typename T2>
//class Test <T1*, T2*>
//{
//public:
//	Test() { cout << "Data<T1*, T2*>" << endl; }
//
//private:
//
//	T1 _d1;
//	T2 _d2;
//};
//
////两个参数偏特化为引用类型
//template <typename T1, typename T2>
//class Test <T1&, T2&>
//{
//public:
//	Test(const T1& d1, const T2& d2)
//		: _d1(d1)
//		, _d2(d2)
//	{
//		cout << "Data<T1&, T2&>" << endl;
//	}
//
//private:
//	const T1& _d1;
//	const T2& _d2;
//};
//
//int main()
//{
//	Test<double, int> t1; // 调用特化的int版本
//	Test<int, double> t2; // 调用基础的模板 
//	Test<int*, int*> t3; // 调用特化的指针版本
//	Test<int&, int&> t4(1, 2); // 调用特化的指针版本
//	return 0;
//}


//#include<vector>
//#include <algorithm>
//
//class Date //日期类
//{
//public:
//	Date() = default;
//	Date(int y, int m, int d)
//		:_y(y)
//		, _m(m)
//		, _d(d)
//	{}
//
//	bool operator<(const Date& d)
//	{
//		return _y < d._y
//			|| _y == d._y && _m < d._m
//			|| _y == d._y && _m == d._m && _d < d._d;
//	}
//
//	bool operator>(const Date& d)
//	{
//		return !(*this < d);
//	}
//
//	int _y;
//	int _m;
//	int _d;
//};
//
//
//// 对Less类模板按照指针方式特化
//template<>
//struct Less<Date*>
//{
//	bool operator()(Date* x, Date* y) const
//	{
//		return *x < *y;
//	}
//};
//
//template<class T> //仿函数
//struct Less
//{
//	bool operator()(const T& x, const T& y) const
//	{
//		return x < y;
//	}
//};
//int main()
//{
//	Date d1(2022, 7, 7);
//	Date d2(2022, 7, 6);
//	Date d3(2022, 7, 8);
//	vector<Date> v1;
//	v1.push_back(d1);
//	v1.push_back(d2);
//	v1.push_back(d3);
//
//	// 可以直接排序，结果是日期升序
//	sort(v1.begin(), v1.end(), Less<Date>());
//	vector<Date*> v2;
//	v2.push_back(&d1);
//	v2.push_back(&d2);
//	v2.push_back(&d3);
//
//	// 可以直接排序，结果错误日期还不是升序，而v2中放的地址是升序
//	// 此处需要在排序过程中，让sort比较v2中存放地址指向的日期对象
//	// 但是走Less模板，sort在排序时实际比较的是v2中指针的地址，因此无法达到预期
//	sort(v2.begin(), v2.end(), Less<Date*>());
//	return 0;
//}

//定义一个相加的仿函数
//template<class T>
//struct Add
//{
//    T operator()(const T& left, const T& right)
//    {
//        return left + right;
//    }
//};
//
//int main()
//{
//    cout << Add<int>()(1, 2) << endl; //通过匿名对象调用仿函数
//    cout << Add<double>()(1.1, 2.2) << endl;
//    return 0;
//}


